package com.contory.ssn_lgnd.framework.gl;

import android.opengl.GLES20;
import android.util.FloatMath;

import com.contory.ssn_lgnd.framework.math.Vector2;

public class SpriteBatcher {        
    final float[] verticesBuffer;
    int bufferIndex;
    final Vertices vertices;
    int numSprites;    
    final boolean hasColor;
    final boolean hasTexCoords = true;
    
    public SpriteBatcher(int maxSprites, boolean hasColor) {                
    	this.hasColor = hasColor;
    	this.verticesBuffer = new float[maxSprites*8*4];        
        this.vertices = new Vertices(maxSprites*4, maxSprites*6, hasColor, hasTexCoords);
        this.bufferIndex = 0;
        this.numSprites = 0;
                
        short[] indices = new short[maxSprites*6];
        int len = indices.length;
        short j = 0;
        for (int i = 0; i < len; i += 6, j += 4) {
                indices[i + 0] = (short)(j + 0);
                indices[i + 1] = (short)(j + 1);
                indices[i + 2] = (short)(j + 2);
                indices[i + 3] = (short)(j + 2);
                indices[i + 4] = (short)(j + 3);
                indices[i + 5] = (short)(j + 0);
        }
        vertices.setIndices(indices, 0, indices.length);                
    }       
    
    public void beginBatch(ESShader shader, TexturePtr dst, String texMapName0, int texActivePos) {
        if(dst != null)
        	dst.bind(shader, texMapName0, texActivePos);
        
        numSprites = 0;
        bufferIndex = 0;
    }
    
    public void beginBatch(ESShader shader, TexturePtr dst, String texMapName0, int texActivePos0,
    		TexturePtr src, String texMapName1, int texActivePos1) {
        if(dst != null)
        	dst.bind(shader, texMapName0, texActivePos0);
        
        if(src != null)
        	src.bind(shader, texMapName1, texActivePos1);
        
        numSprites = 0;
        bufferIndex = 0;
    }
    
    public void endBatch(ESShader shader, String name_h_pos, String name_h_color, String name_h_texCoor, String name_h_hasColor) {
        vertices.setVertices(verticesBuffer, 0, bufferIndex);
        vertices.bind(shader, name_h_pos, name_h_color, name_h_texCoor, name_h_hasColor);
        vertices.draw(GLES20.GL_TRIANGLES, 0, numSprites * 6);
        vertices.unbind(shader, name_h_color, name_h_texCoor);
    }
    
    public void drawSprite(float x, float y, float width, float height, TextureRegion region) {
        float halfWidth = width / 2;
        float halfHeight = height / 2;
        float x1 = x - halfWidth;
        float y1 = y - halfHeight;
        float x2 = x + halfWidth;
        float y2 = y + halfHeight;
        
        verticesBuffer[bufferIndex++] = x1;
        verticesBuffer[bufferIndex++] = y1;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
        }
        verticesBuffer[bufferIndex++] = region.u1;
        verticesBuffer[bufferIndex++] = region.v2;
        
        verticesBuffer[bufferIndex++] = x2;
        verticesBuffer[bufferIndex++] = y1;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
        }
        verticesBuffer[bufferIndex++] = region.u2;
        verticesBuffer[bufferIndex++] = region.v2;
        
        verticesBuffer[bufferIndex++] = x2;
        verticesBuffer[bufferIndex++] = y2;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
        }
        verticesBuffer[bufferIndex++] = region.u2;
        verticesBuffer[bufferIndex++] = region.v1;
        
        verticesBuffer[bufferIndex++] = x1;
        verticesBuffer[bufferIndex++] = y2;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
        }
        verticesBuffer[bufferIndex++] = region.u1;
        verticesBuffer[bufferIndex++] = region.v1;
        
        numSprites++;
    }
    
    public void drawSprite(float x, float y, float width, float height, float rad, TextureRegion region) {
        float halfWidth = width / 2;
        float halfHeight = height / 2;
        
        //float rad = angle * Vector2.TO_RADIANS;
        float cos = FloatMath.cos(rad);
        float sin = FloatMath.sin(rad);
                
        float x1 = -halfWidth * cos - (-halfHeight) * sin;
        float y1 = -halfWidth * sin + (-halfHeight) * cos;
        float x2 = halfWidth * cos - (-halfHeight) * sin;
        float y2 = halfWidth * sin + (-halfHeight) * cos;
        float x3 = halfWidth * cos - halfHeight * sin;
        float y3 = halfWidth * sin + halfHeight * cos;
        float x4 = -halfWidth * cos - halfHeight * sin;
        float y4 = -halfWidth * sin + halfHeight * cos;
        
        x1 += x;
        y1 += y;
        x2 += x;
        y2 += y;
        x3 += x;
        y3 += y;
        x4 += x;
        y4 += y;
        
        verticesBuffer[bufferIndex++] = x1;
        verticesBuffer[bufferIndex++] = y1;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
        }
        verticesBuffer[bufferIndex++] = region.u1;
        verticesBuffer[bufferIndex++] = region.v2;
        
        verticesBuffer[bufferIndex++] = x2;
        verticesBuffer[bufferIndex++] = y2;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
        }
        verticesBuffer[bufferIndex++] = region.u2;
        verticesBuffer[bufferIndex++] = region.v2;
        
        verticesBuffer[bufferIndex++] = x3;
        verticesBuffer[bufferIndex++] = y3;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
        }
        verticesBuffer[bufferIndex++] = region.u2;
        verticesBuffer[bufferIndex++] = region.v1;
        
        verticesBuffer[bufferIndex++] = x4;
        verticesBuffer[bufferIndex++] = y4;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
	        verticesBuffer[bufferIndex++] = 1.0f;
        }
        verticesBuffer[bufferIndex++] = region.u1;
        verticesBuffer[bufferIndex++] = region.v1;
        
        numSprites++;
    }
    
    public void drawRightRect(float x, float y, float width, float height, float r, float g, float b, float a, TextureRegion region) {
        float halfHeight = height / 2;
        float x1 = x;
        float y1 = y - halfHeight;
        float x2 = x + width;
        float y2 = y + halfHeight;
        
        verticesBuffer[bufferIndex++] = x1;
        verticesBuffer[bufferIndex++] = y1;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = r;
	        verticesBuffer[bufferIndex++] = g;
	        verticesBuffer[bufferIndex++] = b;
	        verticesBuffer[bufferIndex++] = a;
        }
        verticesBuffer[bufferIndex++] = region.u1;
        verticesBuffer[bufferIndex++] = region.v2;
        
        
        verticesBuffer[bufferIndex++] = x2;
        verticesBuffer[bufferIndex++] = y1;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = r;
	        verticesBuffer[bufferIndex++] = g;
	        verticesBuffer[bufferIndex++] = b;
	        verticesBuffer[bufferIndex++] = a;
        }
        verticesBuffer[bufferIndex++] = region.u2;
        verticesBuffer[bufferIndex++] = region.v2;
        
        
        verticesBuffer[bufferIndex++] = x2;
        verticesBuffer[bufferIndex++] = y2;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = r;
	        verticesBuffer[bufferIndex++] = g;
	        verticesBuffer[bufferIndex++] = b;
	        verticesBuffer[bufferIndex++] = a;
        }
        verticesBuffer[bufferIndex++] = region.u2;
        verticesBuffer[bufferIndex++] = region.v1;
        
        
        verticesBuffer[bufferIndex++] = x1;
        verticesBuffer[bufferIndex++] = y2;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = r;
	        verticesBuffer[bufferIndex++] = g;
	        verticesBuffer[bufferIndex++] = b;
	        verticesBuffer[bufferIndex++] = a;
        }
        verticesBuffer[bufferIndex++] = region.u1;
        verticesBuffer[bufferIndex++] = region.v1;
        
        numSprites++;
    }
    
    public void drawSprite(float x, float y, float width, float height, float r, float g, float b, float a, TextureRegion region) {
        float halfWidth = width / 2;
        float halfHeight = height / 2;
        float x1 = x - halfWidth;
        float y1 = y - halfHeight;
        float x2 = x + halfWidth;
        float y2 = y + halfHeight;
        
        verticesBuffer[bufferIndex++] = x1;
        verticesBuffer[bufferIndex++] = y1;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = r;
	        verticesBuffer[bufferIndex++] = g;
	        verticesBuffer[bufferIndex++] = b;
	        verticesBuffer[bufferIndex++] = a;
        }
        verticesBuffer[bufferIndex++] = region.u1;
        verticesBuffer[bufferIndex++] = region.v2;
        
        
        verticesBuffer[bufferIndex++] = x2;
        verticesBuffer[bufferIndex++] = y1;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = r;
	        verticesBuffer[bufferIndex++] = g;
	        verticesBuffer[bufferIndex++] = b;
	        verticesBuffer[bufferIndex++] = a;
        }
        verticesBuffer[bufferIndex++] = region.u2;
        verticesBuffer[bufferIndex++] = region.v2;
        
        
        verticesBuffer[bufferIndex++] = x2;
        verticesBuffer[bufferIndex++] = y2;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = r;
	        verticesBuffer[bufferIndex++] = g;
	        verticesBuffer[bufferIndex++] = b;
	        verticesBuffer[bufferIndex++] = a;
        }
        verticesBuffer[bufferIndex++] = region.u2;
        verticesBuffer[bufferIndex++] = region.v1;
        
        
        verticesBuffer[bufferIndex++] = x1;
        verticesBuffer[bufferIndex++] = y2;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = r;
	        verticesBuffer[bufferIndex++] = g;
	        verticesBuffer[bufferIndex++] = b;
	        verticesBuffer[bufferIndex++] = a;
        }
        verticesBuffer[bufferIndex++] = region.u1;
        verticesBuffer[bufferIndex++] = region.v1;
        
        numSprites++;
    }
    
    public void drawSprite(float x, float y, float width, float height, float rad, float r, float g, float b, float a, TextureRegion region) {
        float halfWidth = width / 2;
        float halfHeight = height / 2;
        
        //float rad = angle * Vector2.TO_RADIANS;
        float cos = FloatMath.cos(rad);
        float sin = FloatMath.sin(rad);
                
        float x1 = -halfWidth * cos - (-halfHeight) * sin;
        float y1 = -halfWidth * sin + (-halfHeight) * cos;
        float x2 = halfWidth * cos - (-halfHeight) * sin;
        float y2 = halfWidth * sin + (-halfHeight) * cos;
        float x3 = halfWidth * cos - halfHeight * sin;
        float y3 = halfWidth * sin + halfHeight * cos;
        float x4 = -halfWidth * cos - halfHeight * sin;
        float y4 = -halfWidth * sin + halfHeight * cos;
        
        x1 += x;
        y1 += y;
        x2 += x;
        y2 += y;
        x3 += x;
        y3 += y;
        x4 += x;
        y4 += y;
        
        verticesBuffer[bufferIndex++] = x1;
        verticesBuffer[bufferIndex++] = y1;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = r;
	        verticesBuffer[bufferIndex++] = g;
	        verticesBuffer[bufferIndex++] = b;
	        verticesBuffer[bufferIndex++] = a;
        }
        verticesBuffer[bufferIndex++] = region.u1;
        verticesBuffer[bufferIndex++] = region.v2;
        
        verticesBuffer[bufferIndex++] = x2;
        verticesBuffer[bufferIndex++] = y2;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = r;
	        verticesBuffer[bufferIndex++] = g;
	        verticesBuffer[bufferIndex++] = b;
	        verticesBuffer[bufferIndex++] = a;
        }
        verticesBuffer[bufferIndex++] = region.u2;
        verticesBuffer[bufferIndex++] = region.v2;
        
        verticesBuffer[bufferIndex++] = x3;
        verticesBuffer[bufferIndex++] = y3;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = r;
	        verticesBuffer[bufferIndex++] = g;
	        verticesBuffer[bufferIndex++] = b;
	        verticesBuffer[bufferIndex++] = a;
        }
        verticesBuffer[bufferIndex++] = region.u2;
        verticesBuffer[bufferIndex++] = region.v1;
        
        verticesBuffer[bufferIndex++] = x4;
        verticesBuffer[bufferIndex++] = y4;
        if(hasColor){
	        verticesBuffer[bufferIndex++] = r;
	        verticesBuffer[bufferIndex++] = g;
	        verticesBuffer[bufferIndex++] = b;
	        verticesBuffer[bufferIndex++] = a;
        }
        verticesBuffer[bufferIndex++] = region.u1;
        verticesBuffer[bufferIndex++] = region.v1;
        
        numSprites++;
    }
}